﻿using PlantsZombies.Common;
using PlantsZombies.View.ViewEx;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Media;
using System.Runtime.InteropServices.ComTypes;
using System.Threading;
using System.Windows.Forms;
using WMPLib;

namespace PlantsZombies.View
{
    public unsafe class PlayMap : Control
    {
        private System.Timers.Timer _timer;
        private readonly ImageObject _mapBackground;
        public const int ROWS = 6;
        public const int COLUMNS = 14;
        readonly GameCenter _gameCenter = new GameCenter(ROWS, COLUMNS);
        private readonly Stream _stream;
        readonly WindowsMediaPlayer player;
        public PlayMap()
        {
            SetStyle(
           ControlStyles.ResizeRedraw
           | ControlStyles.DoubleBuffer
           | ControlStyles.UserPaint
           | ControlStyles.AllPaintingInWmPaint
           | ControlStyles.SupportsTransparentBackColor,
           true
           );
            _mapBackground = new ImageObject(Properties.Resources.back);
            _gameCenter.CompletionCallback += _gameCenter_CompletionCallback;

            _timer = new System.Timers.Timer();
            _timer.Interval = 100;
            _timer.Elapsed += _timer_Elapsed;

            this.MouseDown += PlayMap_MouseDown;
            this.MouseUp += PlayMap_MouseUp;
            this.MouseMove += PlayMap_MouseMove;

            string mp = Path.Combine(Application.StartupPath, "Resources\\music\\music.mp3");
            if (File.Exists(mp)) 
            {
                player = new WindowsMediaPlayer();
                player.URL = mp; 
            }
        }

        private void PlayMap_MouseMove(object sender, MouseEventArgs e)
        {
            _gameCenter.MouseMove(sender, e);
        }

        private void PlayMap_MouseUp(object sender, MouseEventArgs e)
        {
            _gameCenter.MouseUp(sender, e);
        }
        private void PlayMap_MouseDown(object sender, MouseEventArgs e)
        {
            _gameCenter.MouseDown(sender, e);
        }

        private int _sunflowerCount = 125;
        public int SunflowerCount
        {
            get { return _sunflowerCount; }
            set { _sunflowerCount = value; }
        }
        private int _radius = 10;
        public int Radius
        {
            get { return _radius; }
            set
            {
                if (value < 0 || value == _radius) return;
                _radius = value;
                this.Invalidate();
            }
        }
        private Padding _borderPadding = new Padding(10, 10, 10, 10);
        public Padding BorderPadding
        {
            get { return _borderPadding; }
            set
            {
                _borderPadding = value;
                this.Invalidate();
            }
        }
        private Color _outColor = Color.FromArgb(141, 66, 42);
        public Color OutColor
        {
            get { return _outColor; }
            set
            {
                _outColor = value;
                this.Invalidate();
            }
        }
        private Color _inColor = Color.FromArgb(103, 46, 17);
        public Color InColor
        {
            get { return _inColor; }
            set
            {
                _inColor = value;
                this.Invalidate();
            }
        }
        private void _gameCenter_CompletionCallback()
        {
            Stop();
            MessageBox.Show("你的脑子被吃掉了！");
        }

        private DateTime _lastTime = DateTime.MinValue;
        DateTime _startTime = DateTime.Now;
        int _defaultTime = 10;
        private void RandomCreationZombie()
        {
            if ((DateTime.Now - _lastTime).TotalSeconds >= _defaultTime)
            {
                _gameCenter.RandomCreationZombie();
                _lastTime = DateTime.Now;
            }
            if ((DateTime.Now - _startTime).TotalSeconds > 48)
            {
                _startTime = DateTime.Now;
                if (--_defaultTime <= 1)
                    _defaultTime = 1;
            }
        }
        private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            _gameCenter.Action();
            RandomCreationZombie();
            if (player != null && player.playState == WMPPlayState.wmppsStopped)
                player.controls.play();
            this.Invalidate();
        }
        public void Start()
        {
            _lastTime = DateTime.Now;
            _gameCenter.Start();
            this.Invalidate();
            _timer.Start();
            if(player!=null)
            {
                player.controls.play();  
            }
        }
        public void Stop()
        {
            if (player != null)
            {
                player.controls.stop();  
            }
            _timer.Stop();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.Smooth();
            IntPtr hdc = e.Graphics.GetHdc();
            // 绘制背景
            DrawBackground(hdc);
            e.Graphics.ReleaseHdc(hdc);

            // 绘制植物、僵尸
            DrawMap(e.Graphics, this.Font);
            // 绘制网格
            //DrawGrid(e.Graphics);

            e.Graphics.Smooth(false);
        }
        private void DrawMap(Graphics g, Font font)
        {
            _gameCenter.Play(g, font);
        }
        const int defaultW = 1011;
        const int defaultH = 600;
        const int _startXDefault = 180;
        const int _startYDefault = 90;
        const int _cellWidthDefault = 60;
        const int _cellHeightDefault = 80;

        private int _startX = 350;
        private int _startY = 170;
        private int _cellWidth = 110;
        private int _cellHeight = 130;
        private float _zoomX = 1f;
        private float _zoomY = 1f;
        protected override void OnSizeChanged(EventArgs e)
        {
            _zoomX = (float)this.Width / defaultW;
            _zoomY = (float)this.Height / defaultH;
            _startX = (int)(_startXDefault * _zoomX);
            _startY = (int)(_startYDefault * _zoomY);
            _cellWidth = (int)(_cellWidthDefault * _zoomX);
            _cellHeight = (int)(_cellHeightDefault * _zoomY);

            _gameCenter.SizeChange(_startX, _startY, _cellWidth, _cellHeight, _zoomX, _zoomY,this.Width,this.Height);

            this.Invalidate();
        }


        private void DrawBackground(IntPtr hdc)
        {
            if (_mapBackground.BitmapPtr != IntPtr.Zero)
            {
                GDI32.DrawImage2(hdc, _mapBackground.BitmapPtr, 0, 0, _mapBackground.Width, _mapBackground.Height, this.Width, this.Height);
            }
        }
        private GraphicsPath GetRoundedRectangle(Rectangle rect, int radius)
        {
            GraphicsPath path = new GraphicsPath();
            var r = radius << 1;
            path.AddArc(rect.X, rect.Y, r, r, 180, 90);
            path.AddLine(rect.X + radius, rect.Y, rect.Right - r, rect.Y);
            path.AddArc(rect.Right - r, rect.Y, r, r, 270, 90);
            path.AddLine(rect.Right, rect.Y + r, rect.Right, rect.Bottom - r);
            path.AddArc(rect.Right - r, rect.Bottom - r, r, r, 0, 90);
            path.AddLine(rect.Right - r, rect.Bottom, rect.X + r, rect.Bottom);
            path.AddArc(rect.X, rect.Bottom - r, r, r, 90, 90);
            path.AddLine(rect.X, rect.Bottom - r, rect.X, rect.Y + radius);

            return path;
        }
        private void DrawGrid(Graphics g)
        {
            Pen pen = new Pen(Color.Red);
            int cellWidth = _cellWidth;
            int cellHeight = _cellHeight;
            int rows = ROWS;
            int cols = COLUMNS;
            int startX = _startX;
            int startY = _startY;
            for (int i = 0; i <= rows; i++)
            {
                g.DrawLine(pen, startX, startY + i * cellHeight, startX + cols * cellWidth, startY + i * cellHeight);
            }

            for (int i = 0; i <= cols; i++)
            {
                g.DrawLine(pen, startX + i * cellWidth, startY, startX + i * cellWidth, startY + rows * cellHeight);
            }
            pen.Dispose();
        }
        protected override void Dispose(bool disposing)
        {
            Stop();
            if (player != null)
            {
                player.close();  // 播放音乐
            }
            base.Dispose(disposing);
            _gameCenter.Dispose();
        }
    }
}
